package com.seeyon.apps.cfca.tools;

import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;

public final class MD5 {
    private static final Logger log = LoggerFactory.getLogger(MD5.class);
    private static char[] digits = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
    private static Map<Character, Integer> rDigits = Maps.newHashMapWithExpectedSize(16);
    private static MessageDigest mHasher;
    private static ReentrantLock opLock;

    public MD5() {
    }

    public static String getMD5String(String content) {
        return bytes2string(hash(content));
    }

    public static String getMD5String16(String content) {
        String str = bytes2string(hash(content));
        return str.substring(8, 24);
    }

    private static byte[] hash(String str) {
        opLock.lock();

        byte[] var2;
        try {
            byte[] bt = mHasher.digest(str.getBytes("UTF-8"));
            if (null == bt || bt.length != 16) {
                throw new IllegalArgumentException("md5 need");
            }

            var2 = bt;
        } catch (UnsupportedEncodingException var6) {
            throw new RuntimeException("unsupported utf-8 encoding", var6);
        } finally {
            opLock.unlock();
        }

        return var2;
    }

    private static String bytes2string(byte[] bt) {
        int l = bt.length;
        char[] out = new char[l << 1];
        int i = 0;

        for(int j = 0; i < l; ++i) {
            out[j++] = digits[(240 & bt[i]) >>> 4];
            out[j++] = digits[15 & bt[i]];
        }

        return new String(out);
    }

    static {
        try {
            mHasher = MessageDigest.getInstance("md5");
        } catch (NoSuchAlgorithmException var1) {
            log.error(var1.getMessage(), var1);
        }

        for(int i = 0; i < digits.length; ++i) {
            rDigits.put(digits[i], i);
        }

        opLock = new ReentrantLock();
    }
}
